<template>
    <div style="height: 100%">
        <a-layout class="main">
            <a-layout-sider v-if="isShow" class="scrollbar" v-model:collapsed="collapsed" theme="dark" :trigger="null" :collapsed-width="10" collapsible>
                <div class="logo">
                    <svg-icon name="logo-name" />
                </div>
                <a-menu class="menuA" v-model:openKeys="menuOpenKeys" v-model:selectedKeys="menuSelectedKeys" theme="dark" mode="inline" @open-change="keys => (menuOpenKeys = [keys.pop()])">
                    <template v-for="item in menus" :key="item.key">
                        <template v-if="!item.children">
                            <a-menu-item :key="item.key" @click="router.push(item.path)">
                                <svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
                                <span>{{ item.title }}</span>
                            </a-menu-item>
                        </template>
                        <template v-else>
                            <a-sub-menu :key="item.key">
                                <template #title>
                                    <svg-icon v-if="item.meta.icon" :name="item.meta.icon" />
                                    <span>{{ item.title }}</span>
                                </template>
                                <a-menu-item v-for="citem in item.children" :key="citem.key" @click="isService(citem)">
                                    <span>{{ citem.title }}</span>
                                </a-menu-item>
                            </a-sub-menu>
                        </template>
                    </template>
                </a-menu>
            </a-layout-sider>
            <a-layout>
                <a-layout-header v-if="isShow" >
                    <div class="breadcrumb-wrap">
                        <a-breadcrumb>
                            <template v-for="(item, i) in useRoute().matched" :key="item.meta.key">
                                <a-breadcrumb-item v-if="i === useRoute().matched.length - 1">{{ item.meta.title || item.name }}</a-breadcrumb-item>
                                <a-breadcrumb-item v-else>
                                    <router-link :to="item.path">{{ item.meta?.title || item.name }}</router-link>
                                </a-breadcrumb-item>
                            </template>
                        </a-breadcrumb>
                    </div>
                    <a-dropdown :trigger="['click']">
                        <a class="ant-dropdown-link" @click="e => e.preventDefault()">
                            <a-space>
                                <a-avatar :size="32">
                                    <template #icon>
                                        <user-outlined />
                                    </template>
                                </a-avatar>
                                <span>{{ userInfo.is_supplier ? userInfo?.company_name : userInfo?.fullname || userInfo?.username }}</span>
                                <caret-down-outlined />
                            </a-space>
                        </a>
                        <template #overlay>
                            <a-menu @click="clickAvatarMenu" theme="dark">
                                <a-menu-item key="password">修改密码</a-menu-item>
                                <a-menu-item v-if="userInfo.is_supplier && !userInfo.certificate_file_path" key="certOpt">证件管理</a-menu-item>
                                <a-menu-divider />
                                <a-menu-item key="logout">退出</a-menu-item>
                            </a-menu>
                        </template>
                    </a-dropdown>
                </a-layout-header>
                <a-layout-content :style="{ padding: 0 }" class="scrollbar">
                    <div class="tabs-wrap" v-if="isShow">
                        <a-tabs v-model:activeKey="tabPaneActiveKey" type="editable-card" hide-add @tab-click="clickTab" @edit="removeTab" @contextmenu.prevent="openContextMenu">
                            <a-tab-pane v-for="pane in tabPanes" :key="pane.path" :closable="pane.closable">
                                <template #tab>
                                    <div :data-path="pane.path">{{ pane.title }}</div>
                                </template>
                            </a-tab-pane>
                        </a-tabs>
                        <ul v-show="contextMenu.visible" :style="{ left: `${contextMenu.clientX}px`, top: `${contextMenu.clientY}px` }" class="context-menu">
                            <li data-action="refresh" @click="clickContextMenu">刷新</li>
                            <li data-action="close" @click="clickContextMenu">关闭当前</li>
                            <li data-action="closeOther" @click="clickContextMenu">关闭非当前</li>
                            <li data-action="closeAll" @click="clickContextMenu">关闭所有</li>
                        </ul>
                    </div>

                    <!--
					key的作用：当多个router使用相同的组件时，组件会被复用。即onMounted只会被调用一次。通过指定不同的key，从而实现强制不复用组件。
					-->
                    <router-view v-slot="{ Component }">
                        <transition name="fade-transform" mode="out-in" appear>
                            <!--
							1.keep-alive先匹配被包含组件的name字段，如果name不可用，则匹配当前组件components配置中的注册名称。
							2.keep-alive不会在函数式组件中正常工作，因为它们没有缓存实例。
							3.当匹配条件同时在include与exclude存在时，以exclude优先级最高。
							4.包含在keep-alive中，但符合exclude，不会调用activated和deactivated。
							-->
                            <keep-alive :include="['Workflow']">
                                <component :is="Component" :key="rvKey"></component>
                            </keep-alive>
                        </transition>
                    </router-view>
                </a-layout-content>
            </a-layout>
        </a-layout>

        <a-modal title="修改密码" :visible="visible" :confirm-loading="loading" ok-text="确定" cancel-text="取消" @ok="savePassword" @cancel="visible = false">
            <!--
			<a-form ref="formRef" :model="formState" :rules="formRules" :label-col="{ span: 6 }" :wrapper-col="{ span: 16 }">
			-->
            <a-form ref="formRef" :model="formState" :rules="formRules" v-bind="{ labelCol: { span: 6 }, wrapperCol: { span: 16 } }">
                <a-form-item label="原密码" name="original">
                    <a-input-password v-model:value="formState.original" type="password" />
                </a-form-item>
                <a-form-item label="新密码" name="latest">
                    <a-input-password v-model:value="formState.latest" type="password" />
                </a-form-item>
                <a-form-item label="确认密码" name="confirm">
                    <a-input-password v-model:value="formState.confirm" type="password" />
                </a-form-item>
            </a-form>
        </a-modal>
        <a-modal title="证件管理" :visible="certVisible" :confirm-loading="loading" ok-text="确定" cancel-text="取消" @ok="saveCert" @cancel="certVisible = false">
            <a-form ref="certFormRef" :model="certFormState" v-bind="{ labelCol: { span: 6 }, wrapperCol: { span: 16 } }">
                <a-form-item label="证件类型" name="certificate_type" :rules="{ required: true, message: '请选择证件类型' }">
                    <a-select
                        v-model:value="certFormState.certificate_type"
                        mode="multiple"
                        :show-search="true"
                        placeholder="请选择证件类型"
                        :options="certificateTypeOptions"
                        option-filter-prop="label"
                    ></a-select>
                </a-form-item>
                <a-form-item label="证件文件信息" name="certificate_file_path" :rules="{ required: true, message: '请上传证件文件' }">
                    <a-upload
                        v-model:file-list="certFormState.certificate_file_path"
                        name="upload"
                        :action="`${baseURL}/contract/upload`"
                        :show-upload-list="true"
                        :headers="{ Authorization: `Bearer ${proxy.$cookies.get('token')}` }"
                        :before-upload="beforeUpload"
                        @change="changeUpload"
                    >
                        <a-button>
                            <template v-if="uploading">
                                <loading-outlined />
                                上传中...
                            </template>
                            <template v-else>
                                <import-outlined />
                                上传附件
                            </template>
                        </a-button>
                    </a-upload>
                    <span style="color: #ccc">
                        提交证件文件
                        <span style="color: red">PNG,JPG,DOC,EXCEL,PDF</span>
                        文件
                    </span>
                </a-form-item>
                <a-form-item label="证件有效期" name="certificate_validity" :rules="{ required: true, message: '请输入有效期' }">
                    <a-checkbox v-model:checked="certFormState.certificate_perpetuity" @change="changeCertificatePerpetuity">长期</a-checkbox>
                    <a-date-picker v-model:value="certFormState.certificate_validity" value-format="YYYY-MM-DD" :disabled="certFormState.certificate_perpetuity" />
                </a-form-item>
            </a-form>
        </a-modal>
        <a-modal title="上传签名" :visible="manuallySignedVisible" :confirm-loading="loading" ok-text="确定" cancel-text="取消" @ok="saveUserManuallySigned" @cancel="manuallySignedVisible = false">
            <a-form ref="manuallySigned" :model="manuallySignedFormState" v-bind="{ labelCol: { style: { width: '100px' } } }">
                <a-form-item label="上传签名照片" name="file_path" :rules="{ required: true, message: '请上传签名照片' }">
                    <a-upload
                        v-model:file-list="manuallySignedFormState.file_path"
                        list-type="picture-card"
                        name="upload"
                        :action="`${baseURL}/contract/upload`"
                        :show-upload-list="true"
                        :headers="{ Authorization: `Bearer ${proxy.$cookies.get('token')}` }"
                        :before-upload="beforeClientUpload"
                        @change="changeClientUpload"
                    >
                        <a-button>
                            <template v-if="manuallySignedFormState.uploading">上传中...</template>
                            <template v-else>上传照片</template>
                        </a-button>
                    </a-upload>
                    <span style="color: #ccc">
                        提交签名图片
                        <span style="color: red">JPG,PNG</span>
                        文件, 尺寸不能超过
                        <span style="color: red">135*60px</span>
                    </span>
                </a-form-item>
            </a-form>
        </a-modal>
    </div>
</template>

<script setup>
import { computed, getCurrentInstance, reactive, ref, toRaw, watch, onMounted, provide } from 'vue';
import { useRoute, useRouter } from 'vue-router';

import { UserOutlined, CaretDownOutlined } from '@ant-design/icons-vue';

import { post } from '../utils';
import { baseURL } from '../utils/request';
const { proxy } = getCurrentInstance();

const rvKey = computed(() => {
    return useRoute().path;
});

const collapsed = ref(false);

import dayjs from 'dayjs';

import { userStore } from '../store';
const store = userStore();
const userInfo = store.info;

const visible = ref(false);
const manuallySignedVisible = ref(false);

const loading = ref(false);

const certVisible = ref(false);
const certFormState = ref({});
const certFormRef = ref(null);
const certificateTypeOptions = ref([]);
const uploading = ref(false);

post('dictionary', { root_id: '1039' }).then(data => {
    certificateTypeOptions.value = data.map(d => {
        return {
            value: d.id,
            label: d.name,
        };
    });
});

const clickAvatarMenu = async e => {
    const { key } = e;
    if (key === 'logout') {
        proxy.$confirm({
            title: '确认提示',
            content: '确定要退出当前系统吗？',
            okText: '确认',
            cancelText: '取消',
            onOk() {
                proxy.$cookies.remove('token');
                proxy.$cookies.remove('_tab_panes');

                window.location.reload();
                return Promise.resolve();
            },
        });
    } else if (key === 'password') {
        visible.value = true;
    } else if (key === 'updateManuallySigned') {
        const user = await post(`/user/mineInfo`);
        manuallySignedVisible.value = true;
        manuallySignedFormState.value = {
            id: user.id,
            file_path: [
                {
                    url: user.manually_signed_file_path,
                },
            ],
        };
    } else if (key === 'certOpt') {
        certVisible.value = true;
    }
};

const formRef = ref();
const formState = reactive({});
const manuallySignedFormState = ref({});
const manuallySigned = ref();

const formRules = reactive({
    original: [{ required: true, message: '请输入原密码', trigger: 'blur' }],
    latest: [
        {
            required: true,
            trigger: 'blur',
            validator: (rule, value) => {
                if (!value) return Promise.reject('请输入新密码');

                if (!new RegExp('(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[^a-zA-Z0-9]).{8,20}').test(value))
                    return Promise.reject('您的密码复杂度太低（密码中必须包含大小字母、数字、特殊字符，长度为8-20个字符）');

                return Promise.resolve();
            },
        },
    ],
    confirm: [
        {
            required: true,
            validator: (rule, value) => {
                if (value !== formState.latest) return Promise.reject('确认密码不一致');

                return Promise.resolve();
            },
            trigger: ['blur'],
        },
    ],
});

const savePassword = async () => {
    formRef.value
        .validate()
        .then(() => {
            proxy.$message.destroy();

            post('user/password', toRaw(formState))
                .then(() => {
                    proxy.$message.success('新密码修改成功', 1).then(async () => {
                        await store.setInfo();

                        visible.value = false;
                    });
                })
                .catch(err => {
                    proxy.$message.error(err);
                });
        })
        .catch(err => {});
};

const saveCert = async () => {
    certFormRef.value
        .validate()
        .then(() => {
            proxy.$message.destroy();
            const params = { ...certFormState.value };
            params.id = userInfo.id;
            if (params.certificate_file_path) params.certificate_file_path = JSON.stringify(params.certificate_file_path);
            params.certificate_type = params.certificate_type.join(',');
            post('user/save', params)
                .then(() => {
                    proxy.$message.success('证件信息修改成功', 1).then(async () => {
                        certVisible.value = false;
                        certFormState.value = {};
                        await store.setInfo();
                    });
                })
                .catch(err => {
                    proxy.$message.error(err);
                });
        })
        .catch(err => {});
};
//上传前校验
const beforeClientUpload = file => {
    manuallySignedFormState.value.uploading = true;
    if (!['image/png', 'image/jpeg'].includes(file.type)) {
        proxy.$message.error('只能上传照片或PDF文件');
        manuallySignedFormState.value.uploading = false;
        return false;
    }
    const isLt10M = file.size / 1024 / 1024 < 10;
    if (!isLt10M) {
        proxy.$message.error('只能上传10MB以下文件');
        manuallySignedFormState.value.uploading = false;
        return false;
    }
    return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = e => {
            const img = new Image();
            img.onload = () => {
                const width = img.width;
                const height = img.height;
                if (parseFloat(width) > 135 || parseFloat(height) > 60) {
                    manuallySignedFormState.value.uploading = false;
                    proxy.$message.error('上传图片尺寸不能超过135*60px');
                    reject(false);
                }
                resolve();
            };
            img.onerror = reject;
            img.src = e.target.result;
        };
        reader.readAsDataURL(file);
    });
};

// 上传并提交文件
const changeClientUpload = ({ file }) => {
    if (file.status === 'done') {
        manuallySignedFormState.value.file_path = [
            {
                name: file.name,
                url: file.response.data.url,
            },
        ];
        manuallySignedFormState.value.uploading = false;
        proxy.$message.success('上传成功');
    }
    if (!file.status) {
        manuallySignedFormState.value.file_path = manuallySignedFormState.value.file_path.filter(item => item.url);
    }
};
function saveUserManuallySigned() {
    manuallySigned.value
        .validate()
        .then(() => {
            proxy.$message.destroy();
            if (!manuallySignedFormState.value.file_path[0].url) {
                return proxy.$message.error('请上传附件');
            }
            const params = { ...manuallySignedFormState.value };
            //params.file_path = JSON.stringify(params.file_path);
            params.file_path = params.file_path[0].url;

            post('user/saveManuallySignedPic', params)
                .then(() => {
                    proxy.$message.success('提交成功', 1);
                    manuallySignedVisible.value = false;
                })
                .catch(err => {
                    proxy.$message.error(err);
                });
        })
        .catch(err => {});
}
watch(visible, value => {
    if (!value) formRef.value.resetFields();
});

const tabPanes = ref([]);
const tabPaneActiveKey = ref();

const route = useRoute();
const isShow = computed(() => {
    return route.name !== 'dataBoardProject' && route.name !== 'dataBoardCompany';
});
const renderTabs = route => {
    tabPanes.value = proxy.$cookies.get('_tab_panes') || [{ title: '控制台', path: '/dashboard', closable: false }];
    const { meta, path, query } = route;
    if (!tabPanes.value.some(d => d.path === path) && !meta.hidden) {
        tabPanes.value.push({
            title: meta.title,
            path,
            query,
            closable: true,
        });
    } else {
        const _tabPane = tabPanes.value.find(d => d.path === path);
        if (_tabPane) {
            _tabPane.query = query || {};
        }
    }

    proxy.$cookies.set('_tab_panes', tabPanes.value);
    tabPaneActiveKey.value = route.path;
};
renderTabs(route);

watch(route, () => {
    renderTabs(route);
});

const router = useRouter();
const clickTab = path => {
    const tab = tabPanes.value.find(item => item.path === path);
    router.push({
        path: tab.path,
        query: tab.query,
    });
};

const removeTab = path => {
    const i = tabPanes.value.findIndex(d => d.path === path);

    //如果关闭的是当前页面
    if (tabPanes.value[i].path === route.path) {
        //查找当前tab的后一tab，如果不存在，则使用前一tab
        const tab = tabPanes.value[i + 1] || tabPanes.value[i - 1];
        //跳转到新的标签页
        router.push({
            path: tab.path,
            query: tab.query,
        });
    }
    tabPanes.value.splice(i, 1);
    proxy.$cookies.set('_tab_panes', tabPanes.value);
};

const contextMenu = ref({});
const openContextMenu = e => {
    const { path } = e.target.dataset;
    if (path === '/dashboard' || !path) {
        contextMenu.value = {
            visible: false,
        };
        return;
    }

    const { clientX, clientY } = e;
    contextMenu.value = {
        clientX: clientX - 200,
        clientY: clientY - 50,
        visible: true,
        path,
    };
};

const clickContextMenu = e => {
    const { action } = e.currentTarget.dataset;
    const { path } = contextMenu.value;

    /* eslint-disable */
    switch (action) {
        case 'refresh':
            if (route.path === path) {
                router.go(0);
            } else {
                router.replace(path);
            }
            break;
        case 'close':
            removeTab(path);
            break;

        case 'closeOther':
            tabPanes.value = tabPanes.value.filter(d => d.path === '/dashboard' || d.path === path);
            proxy.$cookies.set('_tab_panes', tabPanes.value);

            if (route.path !== path) {
                router.push({
                    path,
                });
            }
            break;
        case 'closeAll':
            tabPanes.value = tabPanes.value.filter(d => d.path === '/dashboard');
            proxy.$cookies.set('_tab_panes', tabPanes.value);

            proxy.$router.push({
                path: '/dashboard',
            });
            break;
    }
    /* eslint-enable */

    contextMenu.value.visible = false;
};

onMounted(() => {
    document.querySelector('#app').addEventListener('click', () => {
        contextMenu.value.visible = false;
    });
});
function isService(citem) {
    console.log(citem.name);
    if (citem.name == 'dataBoardProject' || citem.name == 'dataBoardCompany') {
        let routeData = router.resolve({
            name: citem.name,
        });
        window.open(routeData.href, '_blank');
    } else {
        router.push(citem.path);
    }
}
const menus = computed(() => {
    const menus = store.routes
        .map(d => {
            if (d.children) {
                d.children = d.children.filter(c => !c?.meta?.hidden);

                d.children.map(c => {
                    c.key = String(c.meta?.key);
                    c.path = c?.route?.path || c.path;
                    c.title = c?.meta?.title || c.name;
                });

                if (d.children.length === 1) {
                    const { meta } = d.children[0];
                    if (!meta.icon) meta.icon = d.meta.icon;

                    d = d.children[0];
                }
            }

            d.key = String(d.meta?.key);
            d.path = d?.route?.path || d.path;
            d.title = d?.meta?.title || d.name;

            return d;
        })
        .filter(d => !d?.meta?.hidden);

    return menus;
});

const menuOpenKeys = ref([]);
const menuSelectedKeys = ref([]);

watch(
    route,
    value => {
        const { key, _key } =
            menus.value
                .map(d => {
                    if (d.children)
                        return d.children.map(c => {
                            return { ...c, _key: d.key };
                        });
                    return d;
                })
                .flat(Infinity)
                .find(d => d.path === route.path) || {};

        menuOpenKeys.value = [_key];
        menuSelectedKeys.value = [key];
    },
    { immediate: true }
);

const beforeUpload = file => {
    uploading.value = true;
    if (!['image/png', 'image/jpeg', 'application/pdf', 'application/vnd.ms-excel', 'application/msword'].includes(file.type)) {
        proxy.$message.error('只能上传PNG,JPG,DOC,EXCEL,PDF文件');
        uploading.value = false;
        return false;
    }
    const isLt10M = file.size / 1024 / 1024 < 10;
    if (!isLt10M) {
        proxy.$message.error('只能上传10MB以下文件');
        uploading.value = false;
        return false;
    }
};
const changeUpload = ({ file }) => {
    if (file.status === 'done') {
        certFormState.value.certificate_file_path = [
            {
                name: file.name,
                url: file.response.data.url,
            },
        ];
        uploading.value = false;
        certFormState.value.certificate_file_path = certFormState.value.certificate_file_path.filter(item => item.url);
        proxy.$message.success('上传成功');
    }
    if (!file.status) {
        certFormState.value.certificate_file_path = certFormState.value.certificate_file_path.filter(item => item.url);
    }
};

const changeCertificatePerpetuity = () => {
    if (certFormState.value.certificate_perpetuity) {
        certFormState.value.certificate_validity = '9999-12-31';
    } else {
        certFormState.value.certificate_validity = dayjs(new Date()).format('YYYY-MM-DD');
        // formState.value.certificate_validity = null;
    }
};

//供子页面调用closeTab方法
provide('closeTab', path => {
    const index = tabPanes.value.findIndex(d => d.path === route.path);
    if (index > -1) {
        tabPanes.value.splice(index, 1);
        proxy.$cookies.set('_tab_panes', tabPanes.value);
    }

    let query = {};
    const tab = tabPanes.value.find(d => d.path === path);
    if (tab) {
        path = tab.path;
        query = tab.query;
    } else {
        if (!path) {
            const popTab = tabPanes.value.pop();
            path = popTab.path;
            query = popTab.query;
        }
    }
    //跳转新页面
    router.replace({
        query,
        path,
    });
});
</script>

<style scoped lang="scss">
.fade-transform-leave-active,
.fade-transform-enter-active {
    transition: all 0.5s;
}

.fade-transform-enter {
    opacity: 0;
    transform: translateX(-30px);
}

.fade-transform-leave-to {
    opacity: 0;
    transform: translateX(30px);
}

:deep(.ant-menu-title-content) {
    display: flex;
    align-items: center;

    .svg-icon {
        width: 16px;
        height: 16px;
        margin-right: 8px;
    }
}

.main {
    height: 100vh;
    overflow-x: hidden;

    .ant-layout-header {
        background: #FFF;
        // background: #001529;
        z-index: 1;
        padding: 0 16px;
        display: flex;
        justify-content: space-between;
        box-shadow: 0px 0px 40px rgba(83, 88, 93, 0.1);
    }

    .logo {
        display: flex;
        align-items: center;
        height: 64px;
        background: #0b2542;
        margin-bottom: 2px;

        .svg-icon {
            width: 48px;
            height: 48px;
        }

        .icon-logo-name {
            width: 180px;
            height: 36px;
            color: #fff;
            margin-left: 8px;
        }

        h2 {
            font-size: 20px;
            margin: 0 0 0 8px;
            line-height: 1;
            color: #0a5eae;
        }
    }
    .ant-layout-sider{
        background: #0b2542 !important;
    }
    .ant-layout-sider,
    .ant-layout-content {
        height: calc(100vh - 0px);
        // height: calc(100vh - 64px);
        overflow-x: hidden;
        overflow-y: auto;
    }
}

.breadcrumb-wrap {
    // background: #fff;
    padding: 24px 0px;
    color: #fff;
    a {
        // color: #c2c2c2;
    }
    :deep(.ant-breadcrumb-separator) {
        // color: #c2c2c2 !important;
    }
    span {
        // color: #c2c2c2 !important;
    }
}

.tabs-wrap {
    padding: 12px;
    background: #fff;
    margin-top: 10px;

    :deep(.ant-tabs-nav) {
        margin: 0;

        &:before {
            border-bottom: 0;
        }
    }

    :deep(.ant-tabs.ant-tabs-card) .ant-tabs-nav-wrap {
        .ant-tabs-tab {
            height: 32px;
            line-height: 30px;
            border-radius: 4px;
            padding: 0 16px;

            & > div {
                display: flex;
                align-items: center;

                &:before {
                    content: '';
                    display: block;
                    width: 8px;
                    height: 8px;
                    margin: 0 6px 0 -5px;
                    background: #d9d9d9;
                    border-radius: 100%;
                }
            }

            .ant-tabs-tab-remove {
                display: flex;
                transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);

                width: 0;
                height: 16px;
                overflow: hidden;
                border-radius: 100%;

                font-size: 10px;
                padding: 0;
                align-items: center;
                justify-content: center;
            }

            &:hover {
                .ant-tabs-tab-remove {
                    width: 16px;

                    &:hover {
                        background-color: #c0c4cc;
                        color: #fff;
                    }
                }
            }
        }

        .ant-tabs-tab-active {
            border-bottom-color: #f0f0f0;

            & > div {
                &:before {
                    background-color: #1890ff;
                }
            }
        }
    }

    .context-menu {
        margin: 0;
        background: #fff;
        z-index: 3000;
        position: absolute;
        list-style-type: none;
        padding: 5px 0;
        border-radius: 4px;
        font-size: 12px;
        font-weight: 400;
        color: #333;
        box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);

        li {
            margin: 0;
            padding: 7px 16px;
            width: 100px;

            cursor: pointer;

            &:hover {
                background: #eee;
            }
        }
    }
}
// 滚动条样式
.scrollbar {
    // 滚动条整体部分
    &::-webkit-scrollbar {
        width: 4px;
        height: 4px;
        background-color: #fcfcfc;
    }

    &::-webkit-scrollbar-track,
    ::-webkit-scrollbar-thumb {
        border-radius: 999px;
        border: 0px solid transparent;
    }

    &::-webkit-scrollbar-track {
        box-shadow: 1px 1px 5px rgba(0, 0, 0, 0.6) inset;
    }

    &::-webkit-scrollbar-thumb {
        border-radius: 20px;
        min-height: 20px;
        background-clip: content-box;
        box-shadow: 0 0 0 5px rgba(10, 108, 221, 0.459) inset;
    }

    &::-webkit-scrollbar-corner {
        background: transparent;
    }
}
.menuA {
    background: #0b2542 !important;
    :deep(.ant-menu-sub) {
        background: #071e37 !important;
    }
    :deep(.ant-menu-item-selected) {
        background: #163f6f !important;
    }
}
</style>
